/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package database.entitymanager;

import database.entity.ShoppingCart;
import database.entitymanager.exceptions.IllegalOrphanException;
import database.entitymanager.exceptions.NonexistentEntityException;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import database.entity.User;
import database.entity.CartItem;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Stefan
 */
public class ShoppingCartManager {

    public ShoppingCartManager() {
        emf = Persistence.createEntityManagerFactory("WebshopITE");
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(ShoppingCart shoppingCart) {
        if (shoppingCart.getCartItemList() == null) {
            shoppingCart.setCartItemList(new ArrayList<CartItem>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            User user = shoppingCart.getUser();
            if (user != null) {
                user = em.getReference(user.getClass(), user.getUserid());
                shoppingCart.setUser(user);
            }
            List<CartItem> attachedCartItemList = new ArrayList<CartItem>();
            for (CartItem cartItemListCartItemToAttach : shoppingCart.getCartItemList()) {
                cartItemListCartItemToAttach = em.getReference(cartItemListCartItemToAttach.getClass(), cartItemListCartItemToAttach.getCartitemid());
                attachedCartItemList.add(cartItemListCartItemToAttach);
            }
            shoppingCart.setCartItemList(attachedCartItemList);
            em.persist(shoppingCart);
            if (user != null) {
                user.getShoppingCartList().add(shoppingCart);
                user = em.merge(user);
            }
            for (CartItem cartItemListCartItem : shoppingCart.getCartItemList()) {
                ShoppingCart oldShoppingCartOfCartItemListCartItem = cartItemListCartItem.getShoppingCart();
                cartItemListCartItem.setShoppingCart(shoppingCart);
                cartItemListCartItem = em.merge(cartItemListCartItem);
                if (oldShoppingCartOfCartItemListCartItem != null) {
                    oldShoppingCartOfCartItemListCartItem.getCartItemList().remove(cartItemListCartItem);
                    oldShoppingCartOfCartItemListCartItem = em.merge(oldShoppingCartOfCartItemListCartItem);
                }
            }
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(ShoppingCart shoppingCart) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            ShoppingCart persistentShoppingCart = em.find(ShoppingCart.class, shoppingCart.getCartid());
            User userOld = persistentShoppingCart.getUser();
            User userNew = shoppingCart.getUser();
            List<CartItem> cartItemListOld = persistentShoppingCart.getCartItemList();
            List<CartItem> cartItemListNew = shoppingCart.getCartItemList();
            List<String> illegalOrphanMessages = null;
            for (CartItem cartItemListOldCartItem : cartItemListOld) {
                if (!cartItemListNew.contains(cartItemListOldCartItem)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain CartItem " + cartItemListOldCartItem + " since its shoppingCart field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (userNew != null) {
                userNew = em.getReference(userNew.getClass(), userNew.getUserid());
                shoppingCart.setUser(userNew);
            }
            List<CartItem> attachedCartItemListNew = new ArrayList<CartItem>();
            for (CartItem cartItemListNewCartItemToAttach : cartItemListNew) {
                cartItemListNewCartItemToAttach = em.getReference(cartItemListNewCartItemToAttach.getClass(), cartItemListNewCartItemToAttach.getCartitemid());
                attachedCartItemListNew.add(cartItemListNewCartItemToAttach);
            }
            cartItemListNew = attachedCartItemListNew;
            shoppingCart.setCartItemList(cartItemListNew);
            shoppingCart = em.merge(shoppingCart);
            if (userOld != null && !userOld.equals(userNew)) {
                userOld.getShoppingCartList().remove(shoppingCart);
                userOld = em.merge(userOld);
            }
            if (userNew != null && !userNew.equals(userOld)) {
                userNew.getShoppingCartList().add(shoppingCart);
                userNew = em.merge(userNew);
            }
            for (CartItem cartItemListNewCartItem : cartItemListNew) {
                if (!cartItemListOld.contains(cartItemListNewCartItem)) {
                    ShoppingCart oldShoppingCartOfCartItemListNewCartItem = cartItemListNewCartItem.getShoppingCart();
                    cartItemListNewCartItem.setShoppingCart(shoppingCart);
                    cartItemListNewCartItem = em.merge(cartItemListNewCartItem);
                    if (oldShoppingCartOfCartItemListNewCartItem != null && !oldShoppingCartOfCartItemListNewCartItem.equals(shoppingCart)) {
                        oldShoppingCartOfCartItemListNewCartItem.getCartItemList().remove(cartItemListNewCartItem);
                        oldShoppingCartOfCartItemListNewCartItem = em.merge(oldShoppingCartOfCartItemListNewCartItem);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = shoppingCart.getCartid();
                if (findShoppingCart(id) == null) {
                    throw new NonexistentEntityException("The shoppingCart with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            ShoppingCart shoppingCart;
            try {
                shoppingCart = em.getReference(ShoppingCart.class, id);
                shoppingCart.getCartid();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The shoppingCart with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            List<CartItem> cartItemListOrphanCheck = shoppingCart.getCartItemList();
            for (CartItem cartItemListOrphanCheckCartItem : cartItemListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This ShoppingCart (" + shoppingCart + ") cannot be destroyed since the CartItem " + cartItemListOrphanCheckCartItem + " in its cartItemList field has a non-nullable shoppingCart field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            User user = shoppingCart.getUser();
            if (user != null) {
                user.getShoppingCartList().remove(shoppingCart);
                user = em.merge(user);
            }
            em.remove(shoppingCart);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<ShoppingCart> findShoppingCartEntities() {
        return findShoppingCartEntities(true, -1, -1);
    }

    public List<ShoppingCart> findShoppingCartEntities(int maxResults, int firstResult) {
        return findShoppingCartEntities(false, maxResults, firstResult);
    }

    private List<ShoppingCart> findShoppingCartEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(ShoppingCart.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public ShoppingCart findShoppingCart(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(ShoppingCart.class, id);
        } finally {
            em.close();
        }
    }

    public int getShoppingCartCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<ShoppingCart> rt = cq.from(ShoppingCart.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

}
